From ada4e79b32e07d1b31f3aa7a2cfbcf912a5f08f4 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 28 Dec 2005 15:07:43 +0100 Subject: [PATCH] Reorganizes network frontend device unregister and removal, so that occur in the right order and succeed. Now on Closing state we: - stop queue - unbind irq - unregister the device On removal: - end foreign access to TX and RX pages (we cannot do this before) - free_netdev, doing the last stage of destroying an allocated device Makes xm-test network "03_attach_detach_multiple_pos" pass: http://xmtest.dague.org/cgi-bin/display?view=single&testid=1068 Signed-off-by: Murillo F. Bernardes --- .../drivers/xen/netfront/netfront.c | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index 543b970957..eca6b4c888 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -1209,33 +1209,14 @@ static int netfront_remove(struct xenbus_device *dev) DPRINTK("%s\n", dev->nodename); - netif_free(info); - kfree(info); + netif_disconnect_backend(info); + free_netdev(info->netdev); return 0; } -static void netif_free(struct netfront_info *info) -{ - netif_disconnect_backend(info); - close_netdev(info); -} - - static void close_netdev(struct netfront_info *info) -{ - if (info->netdev) { -#ifdef CONFIG_PROC_FS - xennet_proc_delif(info->netdev); -#endif - unregister_netdev(info->netdev); - info->netdev = NULL; - } -} - - -static void netif_disconnect_backend(struct netfront_info *info) { /* Stop old i/f to prevent errors whilst we rebuild the state. */ spin_lock_irq(&info->tx_lock); @@ -1245,18 +1226,36 @@ static void netif_disconnect_backend(struct netfront_info *info) spin_unlock(&info->rx_lock); spin_unlock_irq(&info->tx_lock); +#ifdef CONFIG_PROC_FS + xennet_proc_delif(info->netdev); +#endif + + if (info->irq) + unbind_from_irqhandler(info->irq, info->netdev); + info->evtchn = info->irq = 0; + + del_timer_sync(&info->rx_refill_timer); + + unregister_netdev(info->netdev); +} + + +static void netif_disconnect_backend(struct netfront_info *info) +{ end_access(info->tx_ring_ref, info->tx.sring); end_access(info->rx_ring_ref, info->rx.sring); info->tx_ring_ref = GRANT_INVALID_REF; info->rx_ring_ref = GRANT_INVALID_REF; info->tx.sring = NULL; info->rx.sring = NULL; +} - if (info->irq) - unbind_from_irqhandler(info->irq, info->netdev); - info->evtchn = info->irq = 0; - del_timer_sync(&info->rx_refill_timer); +static void netif_free(struct netfront_info *info) +{ + close_netdev(info); + netif_disconnect_backend(info); + free_netdev(info->netdev); } -- 2.30.2